package howl.types.query;


import howl.model.PMF;
import howl.types.query.Result;
import howl.types.TableDescriptor;
import howl.types.DataProvider;
import howl.types.Datum;
import howl.types.Entry;

import java.util.*;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

public class ResultSet implements Iterator {
	
	private TableDescriptor td;

	protected Hashtable<Date, Result> results;

	private Enumeration e = null;

	private int current = 0;

	public ResultSet(Long[] keys) {
		this.results = new Hashtable<Date, Result>();
		PersistenceManager pm = PMF.get().getPersistenceManager();

			Query query = pm
					.newQuery("select from howl.types.Entry where id == k "
							+ "import howl.types.Entry;");

			query.declareParameters("Long k");

			Query query1 = pm
					.newQuery("select from howl.types.Datum where ParentID == k "
							+ "import howl.types.Entry;");

			query1.declareParameters("Long k");
			
			Query q2 = pm.newQuery("select from howl.types.DataProvider where Name == Param1 && FeedOwner == Param2" +
					" parameters String Param1, Long Param2" +
					" import howl.types.DataProvider;");

			for (int i = 0; i < keys.length; i++) {
				Entry e = ((List<Entry>) query.execute(keys[i])).get(0);
				Result r = new Result(e.getTimestamp());
				List<DataProvider> res = (List<DataProvider>)q2.execute(e.getSensorName(), e.getParentID());
				r.setDp(res.get(0));

				List<Datum> d = (List<Datum>) query1.execute(e.getId());

				for (int j = 0; j < d.size(); j++) {
					item tm = new item(d.get(j).getName(), d.get(j).getUnit(),
							d.get(j).getValue());

					r.put(d.get(j).getName(), tm);

				}
				if (!this.results.containsKey(e.getTimestamp())) {
					this.results.put(e.getTimestamp(), r);
				}
			}
		

	}

	public ResultSet(){
		super();
		this.current = 0;
		this.results = new Hashtable<Date, Result>();
	}
	@Override
	public boolean hasNext() {
		return this.results.size() > this.current;
	}

	@Override
	public Object next() {
		if (this.e == null) {
			this.e = this.results.elements();
		}
		Result r = (Result) this.e.nextElement();
		this.current++;
		return r;
	}

	@Override
	public void remove() {
		// null method
	}

	public void resetEnumerator() {
		this.e = null;
	}

	public int size() {
		return this.results.size();
	}

	public String toXML() {
		if(this.results != null){
		ArrayList l = new ArrayList(this.results.values());
		Collections.sort(l);
		String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><EntrySet>";
		for (int i = 0; i < l.size(); i++) {
			str = str + ((Result) l.get(i)).toXML();
		}
		return str + "</EntrySet>";
		} else {
			return "<?xml version=\"1.0\" encoding=\"utf-8\"?><EntrySet></EntrySet>";
		}
	}



	public String toCSV(){
		if(this.results != null){
	
		ArrayList l = new ArrayList(this.results.values());
		
		
		int FieldNumber = 4 + td.getStringmapper().size();
		String[] line = new String[FieldNumber];
		Hashtable<String,Integer> mapper = new Hashtable<String,Integer>();
		mapper.put("SensorName", 0);
		mapper.put("Longitude", 1);
		mapper.put("Latitude", 2);
		mapper.put("Timestamp", 3);
		line[0] = "SensorName";
		line[1] = "Longitude";
		line[2] = "Latitude";
		line[3] = "Timestamp";
		for(int i = 0; i<td.getStringmapper().size();i++){
			line[4+i] = td.getStringmapper().get(i);
			mapper.put(line[4+i], (4 + i));
		}
		
		String retval = "";
		for(int i = 0; i<line.length;i++){

			if(i==line.length-1){
				retval = retval + line[i] + "\n";
			}else {
				retval = retval + line[i] + " ,";
			}
			
		}
		for(int i = 0; i<l.size();i++){
			Result r = (Result) l.get(i);
			line[mapper.get("SensorName")] = r.getDp().getName();
			line[mapper.get("Longitude")] = Double.valueOf(r.getDp().getLongitude()).toString();
			line[mapper.get("Latitude")] = Double.valueOf(r.getDp().getLatitude()).toString();
			line[mapper.get("Timestamp")] = r.getTimestamp().toGMTString();
			ArrayList  h = new ArrayList(r.getMap().keySet());
			for(int j = 0; j<h.size();j++){
				line[mapper.get(h.get(j))] = r.getValue((String) h.get(j)).getValue().toString();
			}
		
			for(int k = 0; k<line.length;k++){

				if(k==line.length-1){
					retval = retval + line[k] + "\n";
				}else {
					retval = retval + line[k] + " ,";
				}
				
			}
		}
		
		return retval;
		
		}
		return null;
	}


	public Hashtable<Date, Result> getResults() {
		return results;
	}

	/**
	 * @return the td
	 */
	public TableDescriptor getTd() {
		return td;
	}

	/**
	 * @param td the td to set
	 */
	public void setTd(TableDescriptor td) {
		this.td = td;
	}

}
